/*
 *  Netzpult - Your desk on the web
 *  Copyright (C) 2011  Ulrich Hilger, http://uhilger.de
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/
 */

package de.uhilger.netzpult.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.ClosingEvent;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;

import de.uhilger.netzpult.shared.Document;

/**
 * Bedienoberfl�che zum Schreiben von Texten der Webanwenung Netzpult.
 * 
 * @author Copyright (c) Ulrich Hilger, http://uhilger.de
 * @author Published under the terms and conditions of
 * the <a href="http://www.gnu.org/licenses/" target="_blank">GNU General Public License</a>
 */
public class Texter extends AbstrakteGestalt {

	private final OwnerServiceAsync service;
	private Editor editor;
	private TextBox docTitle;
	private Document document;
	private Label docIdLabel;
	private Label docVersionLabel;
	private Label docTimeLabel;
	private Anchor permalink;

	public Texter(final OwnerServiceAsync service, /*final String docId,*/ int height) {
		super();
		this.service = service;
		buildTexter(/*docId,*/ height);
	}

	public void openDocument(final String docId) {
		new GetDocument(service, new SetDocument(), new LoginExitCommand(), docId).execute();
	}
		
	public void setDocument(Document document) {
		this.document = document;
		docTitle.setText(document.getTitle());
		docIdLabel.setText(Integer.toString(document.getId()));
		updateDocumentInfo(document);
		permalink.setHref(GWT.getHostPageBaseURL() + "../dok/" + Integer.toString(document.getId()) + "?draft=yes");
		setEditorText();
		Window.addWindowClosingHandler(new Window.ClosingHandler() {

			@Override
			public void onWindowClosing(ClosingEvent event) {
				event.setMessage("Texter: Nicht gespeicherte Änderungen gehen verloren. Fenster wirklich schließen?");
			}
			
		});
	}
	
	private void updateDocumentInfo(Document document) {
		int version = document.getVersion();
		if(version == Document.DRAFT_VERSION_ID) {
			docVersionLabel.setText("Entwurf");
		} else {
			docVersionLabel.setText(Integer.toString(version));
		}
		//Date date = document.getCreationDateTime();
		//String dateStr = getDateStr(date);
		//GWT.log("updateDocumentInfo " + dateStr);
		docTimeLabel.setText(document.getCreationTimeStr());
	}
	
	/*private String getDateStr(Date date) {
		DateTimeFormat dateFormat = DateTimeFormat.getFormat("dd.MM.yyyy HH:mm:ss");
		return dateFormat.format(date);
	}*/
	
	private void setEditorText() {
		Timer t = new Timer() {
      public void run() {
      	if(!editor.setText(document.getContent())) {
      		setEditorText();
      	}
      }
    };
		t.schedule(200);
	}
	
	public Editor getEditor() {
		return editor;
	}
	
	private void buildTexter(/*String docId,*/ int height) {
		
		/*Button toggleBtn = new Button("Toggle Editor");
		toggleBtn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				editor.toggleEditor();
			}
		});*/

		Button saveDraftBtn = new Button("Entwurf Speichern");
		saveDraftBtn.setHeight("24px");
		saveDraftBtn.setWidth("140px");
		saveDraftBtn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				//saveDraft();
				new SaveDraft(service, new GetResultCommand(), new LoginExitCommand()/*, document*/).execute();
			}
		});
		
		Button saveVersionBtn = new Button("Neue Version Speichern");
		saveVersionBtn.setHeight("24px");
		saveVersionBtn.setWidth("180px");
		saveVersionBtn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				//saveVersion();
				new SaveVersion(service, new GetResultCommand(), new LoginExitCommand()/*, document*/).execute();
			}
		});

		/*Button getTextBtn = new Button("Get Text");
		getTextBtn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				Window.alert(editor.getText());
			}
		});*/

		/*Button setTextBtn = new Button("Set Text");
		setTextBtn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				editor.setText(document.getContent());
			}
		});*/

		Label idLabel = new Label("ID:");
		docIdLabel = new Label();
		Label label = new Label("Titel:");
		docVersionLabel = new Label();
		docVersionLabel.setStyleName("texterDocInfo");
		docTimeLabel = new Label();
		docTimeLabel.setStyleName("texterDocInfo");
		docTitle = new TextBox();
		docTitle.setWidth("200px");
		
		HorizontalPanel topPanel = new HorizontalPanel();
		topPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		topPanel.setSpacing(4);
		topPanel.add(idLabel);
		topPanel.add(docIdLabel);
		topPanel.add(docVersionLabel);
		topPanel.add(docTimeLabel);
		topPanel.add(label);
		topPanel.add(docTitle);
		//topPanel.add(toggleBtn);
		topPanel.add(saveDraftBtn);
		topPanel.add(saveVersionBtn);
		permalink = new Anchor("Vorschau");
		permalink.setTarget("_blank");
		topPanel.add(permalink);
		//topPanel.add(getTextBtn);
		//topPanel.add(setTextBtn);
		
		//RootLayoutPanel rootPanel = RootLayoutPanel.get();
		editor = EditorFactory.getEditor(height /*rootPanel.getOffsetHeight()*/);
		editor.setSize("100%", "100%");

		DockLayoutPanel contentPanel = new DockLayoutPanel(Unit.EM);
		contentPanel.addNorth(topPanel, 3.0);
		contentPanel.add(editor);
				
		initWidget(contentPanel);
	}
	
	/*private void saveDraft() {
		if(document == null) {
			document = new Document();
		}
		String text = editor.getText();
		//Window.alert(text);
		document.setTitle(docTitle.getText());
		document.setContent(text);
		service.saveDraft(document, new AsyncCallback<Document>(){
			public void onFailure(Throwable caught) {
				Window.alert("Webfiles.saveDraft saveDraft error " + caught.getMessage());
			}
			public void onSuccess(Document result) {
				document = result;
				//Window.alert("Document saved as draft");
			}
		});
	}
	
	private void saveVersion() {
		if(document == null) {
			document = new Document();
		}
		String text = editor.getText();
		//Window.alert(text);
		document.setContent(text);
		document.setTitle(docTitle.getText());
		service.createDocument(document, new AsyncCallback<Document>(){
			public void onFailure(Throwable caught) {
				Window.alert("Webfiles.saveVersion createDocument error " + caught.getMessage());
			}
			public void onSuccess(Document result) {
				document = result;
				//Window.alert("Document saved as new version");
			}
		});
	}*/

	@Override
	public int getGestalt() {
		return Gestalt.ID_TEXTER;
	}
	
	/*
	 * Innere Klassen, die relevante Serveraufrufe so verpacken, 
	 * dass sie m�gliche Anmeldeaufforderungen vom Server verarbeiten.
	 */
	
	private class SaveVersion extends ServerCall {
		
		//private Document doc;

		public SaveVersion(Object service, Command nextCommand, Command exitCommand/*, Document doc*/) {
			super(service, nextCommand, exitCommand);
			if(document == null) {
				document = new Document();
			}
			String text = editor.getText();
			document.setContent(text);
			document.setTitle(docTitle.getText());
			//this.doc = doc;
		}

		@SuppressWarnings("unchecked")
		@Override
		public void execute(Object result) {
				if (rpcService != null) {
					((OwnerServiceAsync) rpcService).createDocument(document, this);
				}
		}
		
	}
	
	private class SaveDraft extends ServerCall {

		//private Document doc;
		
		public SaveDraft(Object service, Command nextCommand, Command exitCommand/*, Document doc*/) {
			super(service, nextCommand, exitCommand);
			if(document == null) {
				document = new Document();
			}
			String text = editor.getText();
			document.setTitle(docTitle.getText());
			document.setContent(text);
			//this.doc = doc;
		}

		@SuppressWarnings("unchecked")
		@Override
		public void execute(Object result) {
			if (rpcService != null) {
				((OwnerServiceAsync) rpcService).saveDraft(document, this);
			}
		}
	}
	
	private class GetDocument extends ServerCall {
		private String docId;

		public GetDocument(Object service, Command nextCall, Command exitCall, String docId) {
			super(service, nextCall, exitCall);
			this.docId = docId;
		}

		@SuppressWarnings("unchecked")
		@Override
		public void execute(Object result) {
			if (rpcService != null) {
				((OwnerServiceAsync) rpcService).getDocument(docId, this);
			}
		}
	}

	private class SetDocument extends AbstractLinkedCommand {

		@Override
		public void execute() {
			setDocument((Document) result);
		}
	}
	
	private class GetResultCommand extends AbstractLinkedCommand {

		@Override
		public void execute() {
			document = (Document) result;
			//GWT.log(document.getCreationTimeStr());
			updateDocumentInfo(document);
		}
		
	}

	private class LoginExitCommand extends AbstractLinkedCommand {

		@Override
		public void execute() {
			Window.open("/", "_self", null);
		}

	}
}
